﻿#ifndef NSSHARE_UTILS_HANDY_H_
#define NSSHARE_UTILS_HANDY_H_

namespace nsshare
{
namespace utils
{

template<typename T>
inline void SafeDelete(T & ptr)
{
    if(ptr)
    {
        delete ptr;
        ptr = 0;
    }
}

template<typename T>
inline void SafeRelease(T & ptr)
{
    if(ptr)
    {
        ptr->Release();
        ptr = 0;
    }
}

template<typename T>
inline void SafeDecRef(T & ptr)
{
    if(ptr)
    {
        ptr->DecRef();
        ptr = 0;
    }
}

template<typename T>
inline void SafeFree(T & ptr)
{
    if(ptr)
    {
        free(ptr);
        ptr = 0;
    }
}

template<typename T>
inline size_t countof(const T & arr)
{
    return sizeof(arr) / sizeof(arr[0]);
}

template<typename T>
class ScopePtr
{
public:
    ScopePtr()
        : ptr_(0)
    {
    }

    ScopePtr(T * ptr)
        : ptr_(0)
    {
        ptr_ = ptr;
    }

    ScopePtr<T> & operator=(T * ptr)
    {
        ptr_ = ptr;
        return *this;
    }

    ~ScopePtr()
    {
        if(ptr_)
            delete ptr_;
    }

    void Attach(T * ptr)
    {
        ptr_ = ptr;
    }

    T * Dettach()
    {
        T * ptr = ptr_;
        ptr_ = 0;
        return ptr;
    }

    template<typename Right>
    bool operator==(Right ptr) const
    {
        return ptr_ == ptr;
    }

    template<typename Right>
    bool operator!=(Right ptr) const
    {
        return ptr_ != ptr;
    }

    T * operator->()
    {
        return ptr_;
    }

    operator T *()
    {
        return ptr_;
    }

private:
    T * ptr_;
};

}
}

#endif